// electron开发环境用的插件

import type { Plugin, ViteDevServer } from 'vite'
import type { AddressInfo } from 'net'

import esbuild from 'esbuild'
import electron from 'electron'
import { spawn } from 'child_process'
import fs from 'node:fs'

// electron 不认识ts文件  要编译成js文件
const buildElectron = () => {
  esbuild.buildSync({
    entryPoints: ['src/background.ts'],
    bundle: true,
    outfile: 'dist/background.js',
    platform: 'node',
    target: 'node12',
    external: ['electron']
  })
}

const getElectronProcess = (IP: string) => {
  // 第一个参数是electron的执行文件
  // 进程传参发送给electron
  return spawn(electron as unknown as string, ['dist/background.js', IP])
}

// vite 插件要求必须导出一个对象，此对象必须要有一个name属性
export const ElectronDevPlugin = (): Plugin => {
  return {
    name: 'ElectronDevPlugin',

    // 为了在启动vue的时候顺便把electron带起来，
    // 要用到vite中的configureserver服务，
    // 它是用于配置开发服务器的钩子。
    configureServer(server: ViteDevServer) {
      buildElectron()
      server?.httpServer?.once('listening', () => {
        // 读取vite服务的信息
        const address = server.httpServer?.address() as AddressInfo

        // 拼接ip地址  给electron启动服务时用
        const IP = `http://localhost:${address.port}`

        let electronProcess = getElectronProcess(IP)

        // 监测electron主进程文件
        fs.watchFile('src/background.ts', () => {
          // 杀死当前的Electron进程
          electronProcess.kill()

          // 重新编译主进程代码并重新启动Electron进程
          buildElectron()

          electronProcess = getElectronProcess(IP)
        })

        // 监听Electron进程的stdout输出
        electronProcess.stdout.on('data', (data) => console.log(`日志: ${data}`))
      })
    }
  }
}
